/*
   Copyright (c) 2011, 2012, 2015 Mizar Tools Contributors (mizartools.org)

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
/*  Contributors :
 *	2011-02-04 Marco Riccardi - initial implementation
 *  2012-04-09 Marco Riccardi - added implementation of reduction registration
 *  2015-01-11 Marco Riccardi - added implementation of property registration
 *
 */
package org.mizartools.system;

import java.io.File;

import org.mizartools.system.utility.ConstructorsSignature;
import org.mizartools.system.utility.DefinientiaSignature;
import org.mizartools.system.utility.IdentifyRegistrationsSignature;
import org.mizartools.system.utility.NotationsSignature;
import org.mizartools.system.utility.PropertyRegistrationsSignature;
import org.mizartools.system.utility.ReductionRegistrationsSignature;
import org.mizartools.system.utility.RegistrationsSignature;
import org.mizartools.system.utility.RequirementsSignature;
import org.mizartools.system.utility.SchemesSignature;
import org.mizartools.system.utility.TheoremsSignature;
import org.mizartools.system.xml.Constructors;
import org.mizartools.system.xml.Definientia;
import org.mizartools.system.xml.IdentifyRegistrations;
import org.mizartools.system.xml.Notations;
import org.mizartools.system.xml.PropertyRegistrations;
import org.mizartools.system.xml.ReductionRegistrations;
import org.mizartools.system.xml.Registrations;
import org.mizartools.system.xml.Requirements;
import org.mizartools.system.xml.Schemes;
import org.mizartools.system.xml.Theorems;

public class Article {

	private static String prelPath = EnvironFile.getMIZFILES() + File.separator + "prel";
	private String aid = null;
	private String name = null;
	private String path = null;
	private File fileConstructors = null;
	private File fileDefinientia = null;
	private File fileIdentifyRegistrations = null;
	private File fileNotations = null;
	private File filePropertyRegistrations = null;
	private File fileReductionRegistrations = null;
	private File fileRegistrations = null;
	private File fileRequirements = null;
	private File fileSchemes = null;
	private File fileTheorems = null;
	private ConstructorsImpl constructors = null;
	private NotationsImpl notations = null;
	private DefinientiaImpl definientia = null;
	private RegistrationsImpl registrations = null;
	private RequirementsImpl requirements = null;
	private SchemesImpl schemes = null;
	private TheoremsImpl theorems = null;
	private IdentifyRegistrationsImpl identifyRegistrations = null;	
	private PropertyRegistrationsImpl propertyRegistrations = null;	
	private ReductionRegistrationsImpl reductionRegistrations = null;	

	private ConstructorsSignature constructorsSignature = null;
	private NotationsSignature notationsSignature = null;
	private DefinientiaSignature definientiaSignature = null;
	private RegistrationsSignature registrationsSignature = null;
	private RequirementsSignature requirementsSignature = null;
	private IdentifyRegistrationsSignature identifyRegistrationsSignature = null;
	private PropertyRegistrationsSignature propertyRegistrationsSignature = null;
	private ReductionRegistrationsSignature reductionRegistrationsSignature = null;
	private SchemesSignature schemesSignature = null;
	private TheoremsSignature theoremsSignature = null;

	public Article(String article){
		aid = article.toUpperCase();
		name = article.toLowerCase();
		path = prelPath + File.separator + name.substring(0,1);
	}

	public File fileConstructors(){
		if (fileConstructors == null) fileConstructors = new File(path, name + ".dco"); 
		return fileConstructors;
	}
	
	public boolean hasConstructors(){
		return fileConstructors().exists();
	}

	public File fileDefinientia(){
		if (fileDefinientia == null) fileDefinientia = new File(path, name + ".def"); 
		return fileDefinientia;
	}
	
	public boolean hasDefinientia(){
		return fileDefinientia().exists();
	}

	public File fileIdentifyRegistrations(){
		if (fileIdentifyRegistrations == null) fileIdentifyRegistrations = new File(path, name + ".did"); 
		return fileIdentifyRegistrations;
	}
	
	public boolean hasIdentifyRegistrations(){
		return fileIdentifyRegistrations().exists();
	}

	public File filePropertyRegistrations(){
		if (filePropertyRegistrations == null) filePropertyRegistrations = new File(path, name + ".dpr"); 
		return filePropertyRegistrations;
	}
	
	public boolean hasPropertyRegistrations(){
		return filePropertyRegistrations().exists();
	}
	
	public File fileReductionRegistrations(){
		if (fileReductionRegistrations == null) fileReductionRegistrations = new File(path, name + ".drd"); 
		return fileReductionRegistrations;
	}
	
	public boolean hasReductionRegistrations(){
		return fileReductionRegistrations().exists();
	}

	public File fileNotations(){
		if (fileNotations == null) fileNotations = new File(path, name + ".dno"); 
		return fileNotations;
	}
	
	public boolean hasNotations(){
		return fileNotations().exists();
	}

	public File fileRegistrations(){
		if (fileRegistrations == null) fileRegistrations = new File(path, name + ".dcl"); 
		return fileRegistrations;
	}
	
	public boolean hasRegistrations(){
		return fileRegistrations().exists();
	}

	public File fileRequirements(){
		if (fileRequirements == null) fileRequirements = new File(path, name + ".dre"); 
		return fileRequirements;
	}
	
	public boolean hasRequirements(){
		return fileRequirements().exists();
	}

	public File fileSchemes(){
		if (fileSchemes == null) fileSchemes = new File(path, name + ".sch"); 
		return fileSchemes;
	}
	
	public boolean hasSchemes(){
		return fileSchemes().exists();
	}
	
	public File fileTheorems(){
		if (fileTheorems == null) fileTheorems = new File(path, name + ".the"); 
		return fileTheorems;
	}
	
	public boolean hasTheorems(){
		return fileTheorems().exists();
	}
	
	public String getAid() {
		return aid;
	}

	public String getName() {
		return name;
	}

	public Constructors getConstructors() {
		if (constructors == null && hasConstructors()){
			try {
				constructors = new ConstructorsImpl(fileConstructors());
			} catch (ElementParseException e) {
				e.printStackTrace();
			}
			if (constructors == null) constructors = new ConstructorsImpl();
		}
		if (constructors == null) return null;
		return constructors.getConstructors();
	}

	public Notations getNotations() {
		if (notations == null && hasNotations()){
			try {
				notations = new NotationsImpl(fileNotations());
			} catch (ElementParseException e) {
				e.printStackTrace();
			}
			if (notations == null) notations = new NotationsImpl();
		}
		if (notations == null) return null;
		return notations.getNotations();
	}

	public Registrations getRegistrations() {
		if (registrations == null && hasRegistrations()){
			try {
				registrations = new RegistrationsImpl(fileRegistrations());
			} catch (ElementParseException e) {
				e.printStackTrace();
			}
			if (registrations == null) registrations = new RegistrationsImpl();
		}
		if (registrations == null) return null;
		return registrations.getRegistrations();
	}

	public Requirements getRequirements() {
		if (requirements == null && hasRequirements()){
			try {
				requirements = new RequirementsImpl(fileRequirements());
			} catch (ElementParseException e) {
				e.printStackTrace();
			}
			if (requirements == null) requirements = new RequirementsImpl();
		}
		if (requirements == null) return null;
		return requirements.getRequirements();
	}
	
	public Definientia getDefinientia() {
		if (definientia == null && hasDefinientia()){
			try {
				definientia = new DefinientiaImpl(fileDefinientia());
			} catch (ElementParseException e) {
				e.printStackTrace();
			}
			if (definientia == null) definientia = new DefinientiaImpl();
		}
		return definientia.getDefinientia();
	}

	public IdentifyRegistrations getIdentifyRegistrations() {
		if (identifyRegistrations == null && hasIdentifyRegistrations()){
			try {
				identifyRegistrations = new IdentifyRegistrationsImpl(fileIdentifyRegistrations);
			} catch (ElementParseException e) {
				e.printStackTrace();
			}
			if (identifyRegistrations == null) identifyRegistrations = new IdentifyRegistrationsImpl();
		}
		return identifyRegistrations.getIdentifyRegistrations();
	}

	public PropertyRegistrations getPropertyRegistrations() {
		if (propertyRegistrations == null && hasPropertyRegistrations()){
			try {
				propertyRegistrations = new PropertyRegistrationsImpl(filePropertyRegistrations);
			} catch (ElementParseException e) {
				e.printStackTrace();
			}
			if (propertyRegistrations == null) propertyRegistrations = new PropertyRegistrationsImpl();
		}
		return propertyRegistrations.getPropertyRegistrations();
	}
	
	public ReductionRegistrations getReductionRegistrations() {
		if (reductionRegistrations == null && hasReductionRegistrations()){
			try {
				reductionRegistrations = new ReductionRegistrationsImpl(fileReductionRegistrations);
			} catch (ElementParseException e) {
				e.printStackTrace();
			}
			if (reductionRegistrations == null) reductionRegistrations = new ReductionRegistrationsImpl();
		}
		return reductionRegistrations.getReductionRegistrations();
	}
	
	public Schemes getSchemes() {
		if (schemes == null && hasSchemes()){
			try {
				schemes = new SchemesImpl(fileSchemes);
			} catch (ElementParseException e) {
				e.printStackTrace();
			}
			if (schemes == null) schemes = new SchemesImpl();
		}
		return schemes.getSchemes();
	}
	
	public Theorems getTheorems() {
		if (theorems == null && hasTheorems()){
			try {
				theorems = new TheoremsImpl(fileTheorems);
			} catch (ElementParseException e) {
				e.printStackTrace();
			}
			if (theorems == null) theorems = new TheoremsImpl();
		}
		return theorems.getTheorems();
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((aid == null) ? 0 : aid.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Article other = (Article) obj;
		if (aid == null) {
			if (other.aid != null)
				return false;
		} else if (!aid.equals(other.aid))
			return false;
		return true;
	}

	public ConstructorsSignature getConstructorsSignature() {
		if (constructorsSignature == null) constructorsSignature = ConstructorsSignature.getConstructorsSignature(this); 
		return constructorsSignature;
	}

	public NotationsSignature getNotationsSignature() {
		if (notationsSignature  == null) notationsSignature = NotationsSignature.getNotationsSignature(this); 
		return notationsSignature;
	}

	public DefinientiaSignature getDefinientiaSignature() {
		if (definientiaSignature  == null) definientiaSignature = DefinientiaSignature.getDefinientiaSignature(this); 
		return definientiaSignature;
	}
	
	public RegistrationsSignature getRegistrationsSignature() {
		if (registrationsSignature  == null) registrationsSignature = RegistrationsSignature.getRegistrationsSignature(this); 
		return registrationsSignature;
	}

	public RequirementsSignature getRequirementsSignature() {
		if (requirementsSignature  == null) requirementsSignature = RequirementsSignature.getRequirementsSignature(this); 
		return requirementsSignature;
	}
	
	public IdentifyRegistrationsSignature getIdentifyRegistrationsSignature() {
		if (identifyRegistrationsSignature  == null) identifyRegistrationsSignature = IdentifyRegistrationsSignature.getIdentifyRegistrationsSignature(this); 
		return identifyRegistrationsSignature;
	}

	public PropertyRegistrationsSignature getPropertyRegistrationsSignature() {
		if (propertyRegistrationsSignature  == null) propertyRegistrationsSignature = PropertyRegistrationsSignature.getPropertyRegistrationsSignature(this); 
		return propertyRegistrationsSignature;
	}

	public ReductionRegistrationsSignature getReductionRegistrationsSignature() {
		if (reductionRegistrationsSignature  == null) reductionRegistrationsSignature = ReductionRegistrationsSignature.getReductionRegistrationsSignature(this); 
		return reductionRegistrationsSignature;
	}

	public SchemesSignature getSchemesSignature() {
		if (schemesSignature  == null) schemesSignature = SchemesSignature.getSchemesSignature(this); 
		return schemesSignature;
	}
	
	public TheoremsSignature getTheoremsSignature() {
		if (theoremsSignature  == null) theoremsSignature = TheoremsSignature.getTheoremsSignature(this); 
		return theoremsSignature;
	}
	
}
